/**************************************************************
 * mp3id.h - id3v1 and id3v2.3 partially read write support
 * Copyright (c) 2009  Qin Xiaoxue  <crs.chin@gmail.com>
 *
 * This file is  free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
**************************************************************/


#ifndef __MP3ID_H
#define __MP3ID_H

#ifndef FALSE
#define  FALSE  (0)
#endif

#ifndef TRUE
#define  TRUE  (! TRUE)
#endif


/*****************************************************
                     ID3V1 support
******************************************************/

struct tagID3V1
{
  char header[3];
  char title[30];
  char artist[30];
  char album[30];
  char year[4];
  char comment[28];
  char reserve;
  char track;
  char genre;
} __attribute__((packed));

typedef struct tagID3V1 ID3V1;

#ifndef MAX
#define MAX(a,b)   ((a) > (b) ?  (a) : (b))
#endif

#ifndef MIN
#define MIN(a,b)   ((a) > (b) ?  (b) : (a))
#endif


#ifdef ID3V1_GENRE
/* ID3V1 genres */
#define   BLUES 0
#define   CLASSICROCK  1
#define   COUNTRY  2
#define   DANCE  3
#define   DISCO  4
#define   FUNK  5
#define   GRUNGE  6
#define   HIP_HOP  7
#define   JAZZ  8
#define   METAL  9
#define   NEWAGE  10
#define   OLDIES  11
#define   OTHER  12
#define   POP  13
#define   R_N_B  14
#define   rap  15
#define   REGGAE  16
#define   ROCK  17
#define   TECHNO  18
#define   INDUSTRIAL  19
#define   ALTERNATIVE  20
#define   SKA  21
#define   DEATHMETAL  22
#define   PREANKS  23
#define   SONNDTRACK  24
#define   EURO_TECHNO  25
#define   AMBIENT  26
#define   TRIP_HOP  27
#define   VOCAL  28
#define   JAZZ_FUNK  29
#define   FUSION  30
#define   TRANCE  31
#define   CLASSICAL  32
#define   INSTRUMENTAL  33
#define   ACIDE  34
#define   HOUSE  35
#define   GAME  36
#define   SOUNDCLIP  37
#define   GOSPEL  38
#define   NOISE  39
#define   ALTERNROCK  40
#define   BASS  41
#define   SOUL  42
#define   PUNK  43
#define   SPACE  44
#define   MEDITATIVE  45
#define   INSTRUMENTALPOP  46
#define   INSTRUMENTALROCK  47
#define   ETHNIC  48
#define   GOTHIC  49
#define   DARKWAVE  50
#define   TECHNO_INDUSTRIAL  51
#define   ELECTRONIC  52
#define   POP_FOLK   53
#define   EURODACE  54
#define   DREAM  55
#define   SOUTHERROCK  56
#define   COMEDY  57
#define   CULT  58
#define   GANSTA  59
#define   TOP40  60
#define   CHRISTIANRAP  61
#define   POP_FUNK  62
#define   JUNGLE  63
#define   NATIVEAMERICA  64
#define   CABARET  65
#define   NEWWAVE  66
#define   PSYCHADELIC  67
#define   RAVE  68
#define   SHOWTUNES  69
#define   TRAILER  70
#define   LO_FI  71
#define   TRIBAL  72
#define   ACIDPUNK  73
#define   ACIDJAZZ  74
#define   POLKA  75
#define   RETRO  76
#define   MUSICAL  77
#define   ROCK_ROLL  78
#define   HARDROCK  79

/* extended gneres */
#define   FOLK  80
#define   FOLK_ROCK  81
#define   NATIVEFOLK  82
#define   SWING  83
#define   FASTFUSION  84
#define   BEBOB  85
#define   LATIN  86
#define   REVIVAL  87
#define   CELTIC  88
#define   BLUEGRASS  89
#define   AVANTGARDE  90
#define   GOTHICROCK  91
#define   PROGRESSIVEROCK  92
#define   PSICHEDELICROCK  93
#define   SYMPHONICROCK  94
#define   SLOWROCK  95
#define   BIGBAND  96
#define   CHORUS  97
#define   EASYLISTENING  98
#define   ACOUSTIC  99
#define   HUMOUR  100
#define   SPEECH  101
#define   CHANSON  102
#define   OPERA  103
#define   CHAMBERMUSIC  104
#define   SONATA  105
#define   SYMHONY  106
#define   BOOTYBASS  107
#define   PRIMUS  108
#define   PORNGROOVE  109
#define   SATIRE  110
#define   SLOWJAM  111
#define   CLUB  112
#define   TANGO  113
#define   SAMBA  114
#define   FOLKLORE  115
#define   BALLAD  116
#define   POWERBALLAD  117
#define   RHYTHMICSOUL  118
#define   FREESTYLE  119
#define   DUET  120
#define   PUNKROCK  121
#define   DRUMSOLO  122
#define   ACAPELLA  123
#define   EURO_HOUSE  124
#define   DANCEHALL  125
#define   GOA  126
#define   DRUM_BASS  127
#define   CLUB_HOUSE  128
#define   HARDCORE  129
#define   TERROR  130
#define   INDIE  131
#define   BRITPOP  132
#define   NEGERPUNK  133
#define   PILSKPUNK  134
#define   BEAT  135
#define   CHRISTIANGANGSTARAP  136
#define   HEAVYMETAL  137
#define   BLACKMETAL  138
#define   GROSSOVER  139
#define   CONTEMPORARYCHRISTIAN  140
#define   CHRISTIANROCK  141
#define   MERENGUE  142
#define   SALSA  143
#define   TRASHMETAL  144
#define   ANIME  145
#define   JPOP  146
#define   SYNTHPOP  147
#else
#undef   BLUES
#undef   CLASSICROCK 
#undef   COUNTRY 
#undef   DANCE 
#undef   DISCO 
#undef   FUNK 
#undef   GRUNGE 
#undef   HIP_HOP 
#undef   JAZZ 
#undef   METAL 
#undef   NEWAGE  
#undef   OLDIES  
#undef   OTHER  
#undef   POP  
#undef   R_N_B  
#undef   rap  
#undef   REGGAE  
#undef   ROCK  
#undef   TECHNO  
#undef   INDUSTRIAL  
#undef   ALTERNATIVE  
#undef   SKA  
#undef   DEATHMETAL  
#undef   PREANKS  
#undef   SONNDTRACK  
#undef   EURO_TECHNO  
#undef   AMBIENT  
#undef   TRIP_HOP  
#undef   VOCAL  
#undef   JAZZ_FUNK  
#undef   FUSION  
#undef   TRANCE  
#undef   CLASSICAL  
#undef   INSTRUMENTAL  
#undef   ACIDE  
#undef   HOUSE  
#undef   GAME  
#undef   SOUNDCLIP  
#undef   GOSPEL  
#undef   NOISE  
#undef   ALTERNROCK  
#undef   BASS  
#undef   SOUL  
#undef   PUNK  
#undef   SPACE  
#undef   MEDITATIVE  
#undef   INSTRUMENTALPOP  
#undef   INSTRUMENTALROCK  
#undef   ETHNIC  
#undef   GOTHIC  
#undef   DARKWAVE  
#undef   TECHNO_INDUSTRIAL  
#undef   ELECTRONIC  
#undef   POP_FOLK   
#undef   EURODACE  
#undef   DREAM  
#undef   SOUTHERROCK  
#undef   COMEDY  
#undef   CULT  
#undef   GANSTA  
#undef   TOP40  
#undef   CHRISTIANRAP  
#undef   POP_FUNK  
#undef   JUNGLE  
#undef   NATIVEAMERICA  
#undef   CABARET  
#undef   NEWWAVE  
#undef   PSYCHADELIC  
#undef   RAVE  
#undef   SHOWTUNES  
#undef   TRAILER  
#undef   LO_FI  
#undef   TRIBAL  
#undef   ACIDPUNK  
#undef   ACIDJAZZ  
#undef   POLKA  
#undef   RETRO  
#undef   MUSICAL  
#undef   ROCK_ROLL  
#undef   HARDROCK  

/* extended gneres */
#undef   FOLK  
#undef   FOLK_ROCK  
#undef   NATIVEFOLK  
#undef   SWING  
#undef   FASTFUSION  
#undef   BEBOB  
#undef   LATIN  
#undef   REVIVAL  
#undef   CELTIC  
#undef   BLUEGRASS  
#undef   AVANTGARDE  
#undef   GOTHICROCK  
#undef   PROGRESSIVEROCK  
#undef   PSICHEDELICROCK  
#undef   SYMPHONICROCK  
#undef   SLOWROCK  
#undef   BIGBAND  
#undef   CHORUS  
#undef   EASYLISTENING  
#undef   ACOUSTIC  
#undef   HUMOUR
#undef   SPEECH  
#undef   CHANSON
#undef   OPERA  
#undef   CHAMBERMUSIC  
#undef   SONATA  
#undef   SYMHONY  
#undef   BOOTYBASS  
#undef   PRIMUS  
#undef   PORNGROOVE  
#undef   SATIRE  
#undef   SLOWJAM  
#undef   CLUB  
#undef   TANGO  
#undef   SAMBA  
#undef   FOLKLORE  
#undef   BALLAD  
#undef   POWERBALLAD  
#undef   RHYTHMICSOUL  
#undef   FREESTYLE  
#undef   DUET  
#undef   PUNKROCK  
#undef   DRUMSOLO  
#undef   ACAPELLA  
#undef   EURO_HOUSE  
#undef   DANCEHALL  
#undef   GOA  
#undef   DRUM_BASS  
#undef   CLUB_HOUSE  
#undef   HARDCORE  
#undef   TERROR  
#undef   INDIE  
#undef   BRITPOP  
#undef   NEGERPUNK  
#undef   PILSKPUNK  
#undef   BEAT  
#undef   CHRISTIANGANGSTARAP  
#undef   HEAVYMETAL  
#undef   BLACKMETAL  
#undef   GROSSOVER  
#undef   CONTEMPORARYCHRISTIAN  
#undef   CHRISTIANROCK  
#undef   MERENGUE  
#undef   SALSA  
#undef   TRASHMETAL  
#undef   ANIME  
#undef   JPOP  
#undef   SYNTHPOP  

#endif	/* ID3V1_GENRE */

extern const gchar *genre_list[];
extern const gint genre_list_length;
ID3V1 *check_id3v1(FILE *fp);
int    write_id3v1(FILE *fp, ID3V1 *id);
void   print_id3v1(ID3V1 *id);

/*****************************************************
                     ID3V2.3 support
******************************************************/

/* ID3V2.3 header*/
struct tagID3V23H
{
  char header[3];  /*must be ID3 */
  char version;   /*must be 3 */
  char revision;  /*must be 0 */
  char flag;  /*must be 0 */
  char size[4];
}  __attribute__((packed));

typedef struct tagID3V23H ID3V23H;


/* ID3V2.3 frame header */
struct tagFRAMEH
{
  char frameid[4];
  char size[4];
  char flags[2];
} __attribute__((packed));

typedef struct tagFRAMEH FRAMEH;

typedef struct tagFRAME
{
  FRAMEH frameh;
  char *data;
  int data_len;
  struct tagFRAME *next;
}FRAME;


typedef struct tagID3V23
{
  ID3V23H header;
  int len;
  FRAME *frame;
}ID3V23;


/* frame id's
 *
 * NOTE: the following deffinitions is sequence dependent,don't modify
 * them
 */

#ifdef IDV23_FRAME_ID

#define   AENC  1  /*audio encryption*/
#define   APIC  2  /*attached picture*/

#define   COMM  3  /*comments*/
#define   COMR  4  /*commercial frame*/

#define   ENCR  5  /*encryption  method registration*/
#define   EQUA  6  /*equalization*/
#define   ETCO  7  /*event timing codes*/

#define   GEOB  8  /*general encapsulated object*/
#define   GRID  9  /*group identification registration*/

#define   IPLS  10  /*involved people list*/

#define   LINK  11  /*linked infomation*/

#define   MCDI  12  /*music cd identifacation*/
#define   MLLT  13  /*MPEG location lookup table*/

#define   OWNE  14  /*ownership frame*/

#define   PRIV  15  /*private frame*/
#define   PCNT  16  /*play counter*/
#define   POPM  17  /*popularimeter*/
#define   POSS  18  /*postion synchronisation frame*/

#define   RBUF  19  /*recommanded buffer size*/
#define   RVAD  20  /*relative volumn adjustment*/
#define   RVRB  21  /*reverb*/

#define   SYLT  22  /*synchronized lyric/text*/
#define   SYTC  23  /*synchronized tempo codes*/

#define   TALB  24  /*album/movie/show title*/
#define   TBPM  25  /*BPM (beats per minute)*/
#define   TCOM  26  /*composer*/
#define   TCON  27  /*content type*/
#define   TCOP  28  /*copyight messege*/
#define   TDAT  29  /*date*/
#define   TDLY  30  /*playlist delay*/
#define   TEXT  31  /*lyricist/text writer*/
#define   TFLT  32  /*file type*/
#define   TIME  33  /*time*/
#define   TIT1  34  /*content group description*/
#define   TIT2  35  /*title/ongname/content description*/
//#define   TIT2  36  /*subtitle/description refinement*/
#define   TIT3  36  /*subtitle/description refinement*/
#define   TKEY  37  /*initial key*/
#define   TLAN  38  /*languages*/
#define   TLEN  39  /*length*/
#define   TMED  40  /*media type*/
#define   TOAL  41  /*original album/movie/show title*/
#define   TOFN  42  /*original  file name*/
#define   TOLY  43  /*original lyricist(s)/text writer(s)*/   
#define   TOPE  44  /*original artist(s)/performer(s)*/
#define   TORY  45  /*original release year*/
#define   TOWN  46  /*file owner/license*/
#define   TPE1  47  /*lead performer(s)/soloist(t)*/
#define   TPE2  48  /*band/orchestra/accompaniment*/
#define   TP3E  49  /*conductor/performer refinement*/
#define   TPE4  50  /*interpreted, remixed, or otherwise modifiedby*/
#define   TPOS  51  /*part of a set*/
#define   TPUB  52  /*publisher*/
#define   TRCK  53  /*track number/position in set*/
#define   TRDA  54  /*recording/dates*/
#define   TRSN  55  /*internet radio station name*/
#define   TRSO  56  /*internet radio station owner*/
#define   TSIZ  57  /*size*/
#define   TSRC  58  /*isrc (international statard recording code)*/
#define   TSSE  59  /*software /hardware and settings used for encoding*/
#define   TYER  60  /*year*/
#define   TXXX  61  /*user defined text information frame*/

#define   UFID  62  /*unique file identifier*/
#define   USER  63  /*terms of use*/
#define   USLT  64  /*unsychronized lyric/text transicription*/

#define   WCOM  65  /*coercial infomation*/
#define   WCOP  66  /*copyright/legal infomation*/
#define   WOAF  67  /*offcial audio file webpage*/
#define   WOAR  68  /*official artist/performer webpage*/
#define   WOAS  69  /*official audio source webpage*/
#define   WORS  70  /*officical internet radio station homepage*/
#define   WPAY  71  /*payment*/
#define   WPUB  72  /*publishers official webpage*/
#define   WXXX  73  /*user defined URL link frame*/

#define   TEND  74  /* frame id ends here*/

#else

#undef   AENC
#undef   APIC

#undef   COMM
#undef   COMR

#undef   ENCR
#undef   EQUA
#undef   ETCO

#undef   GEOB
#undef   GRID

#undef   IPLS

#undef   LINK

#undef   MCDI
#undef   MLLT

#undef   OWNE

#undef   PRIV
#undef   PCNT
#undef   POPM
#undef   POSS

#undef   RBUF
#undef   RVAD
#undef   RVRB

#undef   SYLT
#undef   SYTC

#undef   TALB
#undef   TBPM
#undef   TCOM
#undef   TCON
#undef   TCOP
#undef   TDAT
#undef   TDLY
#undef   TEXT
#undef   TFLT
#undef   TIME
#undef   TIT1
#undef   TIT2
//#define   TIT2  36  /*subtitle/description refinement*/
#undef   TIT3
#undef   TKEY
#undef   TLAN
#undef   TLEN
#undef   TMED
#undef   TOAL
#undef   TOFN
#undef   TOLY
#undef   TOPE
#undef   TORY
#undef   TOWN
#undef   TPE1
#undef   TPE2
#undef   TP3E
#undef   TPE4
#undef   TPOS
#undef   TPUB
#undef   TRCK
#undef   TRDA
#undef   TRSN
#undef   TRSO
#undef   TSIZ
#undef   TSRC
#undef   TSSE
#undef   TYER
#undef   TXXX

#undef   UFID
#undef   USER
#undef   USLT

#undef   WCOM
#undef   WCOP
#undef   WOAF
#undef   WOAR
#undef   WOAS
#undef   WORS
#undef   WPAY
#undef   WPUB
#undef   WXXX

#undef   TEND

#endif	/* IDV23_FRAME_ID */

int     has_id3v23(FILE *fp);
ID3V23 *check_id3v23(FILE *fp);
int     write_id3v23_frame(ID3V23 *id3, int frameid, char *data, int len);
int     read_id3v23_frame(ID3V23 *id3, int frameid, char **data, int *len);

/*this will overwrite preexist ID3V2.3 info*/
int     id3v23_attach(FILE *fp, ID3V23 *id3);
void    free_id3v23(ID3V23 *id3);
void    print_id3v23_info(ID3V23 *id3, int all);


/* guess title and artist from file name when there is no id3 tags */
char *guess_filename(const char *str, char **artist);


/* glue code from mp3id.c to metainfo.c */
#include "metainfo.h"

gboolean mp3_probe(FILE *fp);
gboolean mp3_read(FILE *fp, struct meta *meta);
/* gboolean mp3_write(FILE *fp, struct meta *meta); */
/* gchar   *mp3_get_property(struct meta *meta, const gchar *property); */
/* gboolean mp3_set_property(struct meta *meta, const gchar *property, const gchar *value); */
gboolean mp3_release(struct meta *meta);

#endif   /*__MP3ID_H */

